package net.cassite.daf4j.jpa;

import net.cassite.daf4j.DataComparable;
import net.cassite.daf4j.IData;
import net.cassite.daf4j.ParameterComparable;
import net.cassite.daf4j.PreResult;
import net.cassite.daf4j.ds.ExpressionParser;
import net.cassite.daf4j.ds.ObjectResolver;

/**
 * 将表达式解释成JPQL语句
 */
public class JPQLExpParser implements ExpressionParser<JPQLContext, String> {
        private ObjectResolver<JPQLContext, String> objectResolver;

        @Override
        public String add(JPQLContext jpqlContext, Object o, Object o1) throws Exception {
                return objectResolver.resolve(jpqlContext, o) + " + " + objectResolver.resolve(jpqlContext, o1);
        }

        @Override
        public String minus(JPQLContext jpqlContext, Object o, Object o1) throws Exception {
                return objectResolver.resolve(jpqlContext, o) + " - " + objectResolver.resolve(jpqlContext, o1);
        }

        @Override
        public String multi(JPQLContext jpqlContext, Object o, Object o1) throws Exception {
                return objectResolver.resolve(jpqlContext, o) + " * " + objectResolver.resolve(jpqlContext, o1);
        }

        @Override
        public String divide(JPQLContext jpqlContext, Object o, Object o1) throws Exception {
                return objectResolver.resolve(jpqlContext, o) + " / " + objectResolver.resolve(jpqlContext, o1);
        }

        @Override
        public String mod(JPQLContext jpqlContext, Object o, Object o1) throws Exception {
                return "MOD(" + objectResolver.resolve(jpqlContext, o) + ", " + objectResolver.resolve(jpqlContext, o1) + ")";
        }

        @Override
        public String sum(JPQLContext jpqlContext, DataComparable<?> dataComparable) throws Exception {
                return "SUM(" + objectResolver.resolve(jpqlContext, dataComparable) + ")";
        }

        @Override
        public String avg(JPQLContext jpqlContext, DataComparable<?> dataComparable) throws Exception {
                return "AVG(" + objectResolver.resolve(jpqlContext, dataComparable) + ")";
        }

        @Override
        public String count(JPQLContext jpqlContext, DataComparable<?> dataComparable) throws Exception {
                return "COUNT(" + objectResolver.resolve(jpqlContext, dataComparable) + ")";
        }

        @Override
        public String count(JPQLContext jpqlContext, Object entity) throws Exception {
                return "COUNT(" + objectResolver.resolve(jpqlContext, entity) + ")";
        }

        @Override
        public String max(JPQLContext jpqlContext, DataComparable<?> dataComparable) throws Exception {
                return "MAX(" + objectResolver.resolve(jpqlContext, dataComparable) + ")";
        }

        @Override
        public String min(JPQLContext jpqlContext, DataComparable<?> dataComparable) throws Exception {
                return "MIN(" + objectResolver.resolve(jpqlContext, dataComparable) + ")";
        }

        @Override
        public String exists(JPQLContext jpqlContext, PreResult<?> preResult) throws Exception {
                return "EXISTS(" + objectResolver.resolve(jpqlContext, preResult) + ")";
        }

        @Override
        public String notExists(JPQLContext jpqlContext, PreResult<?> preResult) throws Exception {
                return "NOT EXISTS(" + objectResolver.resolve(jpqlContext, preResult) + ")";
        }

        @Override
        public String unary_negative(JPQLContext jpqlContext, ParameterComparable<?> parameterComparable) throws Exception {
                return "-" + objectResolver.resolve(jpqlContext, parameterComparable);
        }

        @Override
        public String concat(JPQLContext jpqlContext, IData<String> iData, String s) throws Exception {
                return "CONCAT(" + objectResolver.resolve(jpqlContext, iData) + ", " + objectResolver.resolve(jpqlContext, s) + ")";
        }

        @Override
        public String concat(JPQLContext jpqlContext, String s, IData<String> iData) throws Exception {
                return "CONCAT(" + objectResolver.resolve(jpqlContext, s) + ", " + objectResolver.resolve(jpqlContext, iData) + ")";
        }

        @Override
        public String concat(JPQLContext jpqlContext, IData<String> iData, IData<String> iData1) throws Exception {
                return "CONCAT(" + objectResolver.resolve(jpqlContext, iData) + ", " + objectResolver.resolve(jpqlContext, iData1) + ")";
        }

        @Override
        public String substring(JPQLContext jpqlContext, IData<String> iData, int i, int i1) throws Exception {
                return "SUBSTRING(" + objectResolver.resolve(jpqlContext, iData) + ", " + objectResolver.resolve(jpqlContext, i) + ", " + objectResolver.resolve(jpqlContext, i1) + ")";
        }

        @Override
        public String trim(JPQLContext jpqlContext, IData<String> iData) throws Exception {
                return "TRIM(" + objectResolver.resolve(jpqlContext, iData) + ")";
        }

        @Override
        public String lower(JPQLContext jpqlContext, IData<String> iData) throws Exception {
                return "LOWER(" + objectResolver.resolve(jpqlContext, iData) + ")";
        }

        @Override
        public String upper(JPQLContext jpqlContext, IData<String> iData) throws Exception {
                return "UPPER(" + objectResolver.resolve(jpqlContext, iData) + ")";
        }

        @Override
        public String length(JPQLContext jpqlContext, IData<String> iData) throws Exception {
                return "LENGTH(" + objectResolver.resolve(jpqlContext, iData) + ")";
        }

        @Override
        public String locate(JPQLContext jpqlContext, IData<String> iData, String s) throws Exception {
                return "LOCATE(" + objectResolver.resolve(jpqlContext, iData) + ", " + objectResolver.resolve(jpqlContext, s) + ")";
        }

        @Override
        public String locate(JPQLContext jpqlContext, IData<String> iData, IData<String> iData1) throws Exception {
                return "LOCATE(" + objectResolver.resolve(jpqlContext, iData) + ", " + objectResolver.resolve(jpqlContext, iData1) + ")";
        }

        @Override
        public String locate(JPQLContext jpqlContext, String s, IData<String> iData) throws Exception {
                return "LOCATE(" + objectResolver.resolve(jpqlContext, s) + ", " + objectResolver.resolve(jpqlContext, iData) + ")";
        }

        @Override
        public void setObjectResolver(ObjectResolver<JPQLContext, String> objectResolver) {
                this.objectResolver = objectResolver;
        }
}
